package graphicalUserInterface;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.jCharts.chartData.ChartDataException;
import org.jCharts.properties.PropertyException;
import org.xml.sax.SAXException;

import chart.PieChartCategory;
import chart.PieChartSource;

import settings.MasterController;
import system.Init;
import entity.Expense;
import entity.Goal;
import entity.Income;
import exception.IllegalInput;
import exception.NullVariableFound;

//@author U096819H
public class HomeScreen extends Shell {

	private Table expense_table;
	private Table income_table;
	private Table goal_table;
	private String[] cashflow_titles = { "Title", "Category", "Amount (SGD)",
			"Money Source", "Date Created", "Recurring" };
	private String[] goal_titles = { "Title", "Total Amount",
			"Amount Achieved", "Active", "Start Date", "End Date" };
	private String[] pieChart_titles = { "Category", "Money Source" };
	private Text txtSearch;
	private String imageDir = "images";
	private String graphDir = "graphs";
	private Image image;
	final MasterController mc = new MasterController();

	// System Entry Point - GUI
	// @author U096819H
	public static void main(String args[]) {
		try {
			Display display = Display.getDefault();
			HomeScreen shell = new HomeScreen(display, 0);
			// loading
			Loading loading = new Loading(shell, 30);
			loading.open(shell.mc, "System Initializing ...");
			shell.close();
			shell = new HomeScreen(display);
			shell.open();
			shell.layout();
			while (!shell.isDisposed()) {
				if (!display.readAndDispatch()) {
					display.sleep();
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// @author U096819H
	HomeScreen(final Display display, int i)
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {
		super(display, SWT.CLOSE | SWT.MIN | SWT.TITLE);
		setLayout(new FormLayout());
	}

	// @author U096819H
	public HomeScreen(final Display display)
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {
		super(display, SWT.CLOSE | SWT.MIN | SWT.TITLE);
		setLayout(new FormLayout());

		// Composite definitions
		final Composite home_composite = new Composite(this, SWT.NONE);
		final Composite pieChartHolder = new Composite(this, SWT.NONE);
		Composite pieChartMenu = new Composite(pieChartHolder, SWT.NONE);
		final Composite incomePie = new Composite(pieChartHolder, SWT.NONE);
		final Composite expensePie = new Composite(pieChartHolder, SWT.NONE);
		final Composite mainMenuHolder = new Composite(this, SWT.NONE);
		Composite searchHolder = new Composite(this, SWT.NONE);

		// UI elements definition
		Label pieChatLbl = new Label(pieChartMenu, SWT.NONE);
		final Combo pieChartType = new Combo(pieChartMenu, SWT.READ_ONLY);

		Label lineTop = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);
		FormData fd_lineTop = new FormData();
		fd_lineTop.right = new FormAttachment(0, 774);
		fd_lineTop.top = new FormAttachment(0, 60);
		fd_lineTop.left = new FormAttachment(0, 10);
		lineTop.setLayoutData(fd_lineTop);
		createContents();

		FormData fd_home_composite = new FormData();
		fd_home_composite.bottom = new FormAttachment(0, 552);
		fd_home_composite.right = new FormAttachment(0, 550);
		fd_home_composite.top = new FormAttachment(0, 73);
		fd_home_composite.left = new FormAttachment(0, 10);
		home_composite.setLayoutData(fd_home_composite);
		home_composite.setVisible(true);
		// IMPT :: initial display
		try {
			showTabHolder(home_composite, "");
			refreshCatPie(incomePie, expensePie, display);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		// Composite:: Search Holder
		FormData fd_searchHolder = new FormData();
		fd_searchHolder.right = new FormAttachment(lineTop, 0, SWT.RIGHT);
		fd_searchHolder.bottom = new FormAttachment(0, 49);
		fd_searchHolder.top = new FormAttachment(0, 10);
		fd_searchHolder.left = new FormAttachment(0, 431);
		searchHolder.setLayoutData(fd_searchHolder);

		// Search:: Text
		txtSearch = new Text(searchHolder, SWT.BORDER);
		txtSearch.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				txtSearch.setText("");
			}
		});
		txtSearch.setText("Keyword Search");
		txtSearch.setBounds(0, 10, 263, 21);

		// Search:: Cancel Search
		Image searchCancelImg = new Image(display, imageDir
				+ "/searchCancelIcon.png");
		Button btnSearchCancel = new Button(searchHolder, SWT.NONE);
		btnSearchCancel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				try {
					refreshExpenseTable("");
					refreshIncomeTable("");
					refreshGoalTable("");
					txtSearch.setText("Keyword Search");
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		btnSearchCancel.setBounds(304, 8, 29, 25);
		btnSearchCancel.setImage(searchCancelImg);

		// Search:: Execute Search
		Image searchImg = new Image(display, imageDir + "/searchIcon.png");
		Button btnSearch = new Button(searchHolder, SWT.NONE);
		btnSearch.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				try {
					refreshExpenseTable(txtSearch.getText());
					refreshIncomeTable(txtSearch.getText());
					// refreshGoalTable(txtSearch.getText());
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		btnSearch.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
			}
		});
		btnSearch.setImage(searchImg);
		btnSearch.setBounds(269, 8, 29, 25);
		// Composite:: End Search Holder

		// Composite:: Menu Holder
		mainMenuHolder.setLayout(new GridLayout(5, false));
		FormData fd_mainMenuHolder = new FormData();
		fd_mainMenuHolder.bottom = new FormAttachment(0, 49);
		fd_mainMenuHolder.right = new FormAttachment(0, 183);
		fd_mainMenuHolder.top = new FormAttachment(0, 10);
		fd_mainMenuHolder.left = new FormAttachment(0, 10);
		mainMenuHolder.setLayoutData(fd_mainMenuHolder);

		// Button:: View Statistics
		Image statsImg = new Image(display, imageDir + "/statsIcon.png");
		Button btnStats = new Button(mainMenuHolder, SWT.NONE);
		btnStats.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true,
				1, 1));
		btnStats.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				StatisticsView sv = new StatisticsView(home_composite
						.getShell(), 65);
				sv.open(mc);
				try {
					refreshExpenseTable("");
					refreshIncomeTable("");
					refreshGoalTable("");
					pieChartType.select(0);
					refreshCatPie(incomePie, expensePie, display);
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		btnStats.setImage(statsImg);

		// Button:: Add New
		Image addImg = new Image(display, imageDir + "/addIcon.png");
		Button btnAddNew = new Button(mainMenuHolder, SWT.NONE);
		btnAddNew.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true,
				1, 1));
		btnAddNew.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				try {
					AddItem additem = new AddItem(home_composite.getShell(), 65);
					additem.open(mc);
					refreshExpenseTable("");
					refreshIncomeTable("");
					refreshGoalTable("");
					pieChartType.select(0);
					refreshCatPie(incomePie, expensePie, display);
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		btnAddNew.setImage(addImg);
		Image undoImg = new Image(display, imageDir + "/undoIcon.png");
		Button btnUndo = new Button(mainMenuHolder, SWT.NONE);
		btnUndo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true, 1,
				1));
		btnUndo.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				try {
					mc.Undo();
					refreshExpenseTable("");
					refreshIncomeTable("");
					refreshGoalTable("");
					pieChartType.select(0);
					refreshCatPie(incomePie, expensePie, display);
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		btnUndo.setImage(undoImg);

		Label label = new Label(mainMenuHolder, SWT.SEPARATOR | SWT.VERTICAL);
		label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, true, 1,
				1));

		// Button:: Settings
		Image settingsImg = new Image(display, imageDir + "/settingsIcon.png");
		Button btnSettings = new Button(mainMenuHolder, SWT.NONE);
		btnSettings.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				true, 1, 1));
		btnSettings.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				try {
					SettingsScreen ss = new SettingsScreen(home_composite
							.getShell(), 65);
					ss.open(mc);
					refreshExpenseTable("");
					refreshIncomeTable("");
					refreshGoalTable("");
					pieChartType.select(0);
					refreshCatPie(incomePie, expensePie, display);
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}

			}
		});
		btnSettings.setImage(settingsImg);
		// Composite:: Menu Holder End

		// Composite:: Pie Chart Holder
		pieChartHolder.setLayout(new FormLayout());
		FormData fd_pieChartHolder = new FormData();
		fd_pieChartHolder.bottom = new FormAttachment(home_composite, 0,
				SWT.BOTTOM);
		fd_pieChartHolder.top = new FormAttachment(lineTop, 11);
		fd_pieChartHolder.right = new FormAttachment(lineTop, 0, SWT.RIGHT);
		fd_pieChartHolder.left = new FormAttachment(home_composite, 6);
		pieChartHolder.setLayoutData(fd_pieChartHolder);

		FormData fd_pieChartMenu = new FormData();
		fd_pieChartMenu.bottom = new FormAttachment(0, 30);
		fd_pieChartMenu.right = new FormAttachment(0, 218);
		fd_pieChartMenu.top = new FormAttachment(0);
		fd_pieChartMenu.left = new FormAttachment(0);
		pieChartMenu.setLayoutData(fd_pieChartMenu);
		pieChartMenu.setLayout(new GridLayout(2, false));

		pieChatLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));
		pieChatLbl.setText("View chat for:");

		pieChartType.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (pieChartType.getSelectionIndex() == 0) {
					// Category Pie Chart
					refreshCatPie(incomePie, expensePie, display);
				} else {
					// Source Pie Chart
					refreshSrcPie(incomePie, expensePie, display);
				}
			}
		});
		pieChartType.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 1, 1));
		pieChartType.setItems(pieChart_titles);
		pieChartType.select(0);

		FormData fd_expensePie = new FormData();
		fd_expensePie.bottom = new FormAttachment(pieChartMenu, 224, SWT.BOTTOM);
		fd_expensePie.top = new FormAttachment(pieChartMenu, 6);
		fd_expensePie.right = new FormAttachment(pieChartMenu, 0, SWT.RIGHT);
		fd_expensePie.left = new FormAttachment(0);
		expensePie.setLayoutData(fd_expensePie);

		FormData fd_incomePie = new FormData();
		fd_incomePie.bottom = new FormAttachment(expensePie, 225, SWT.BOTTOM);
		fd_incomePie.right = new FormAttachment(pieChartMenu, 0, SWT.RIGHT);
		fd_incomePie.top = new FormAttachment(expensePie, 6);
		fd_incomePie.left = new FormAttachment(0);
		incomePie.setLayoutData(fd_incomePie);
		// Composite:: End Pie Chart Holder
	}

	// @author U096819H
	// Display Tab Folder
	public void showTabHolder(final Composite home_composite, String _search)
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException, NullVariableFound {

		String search = _search;
		final TabFolder tableHolder = new TabFolder(home_composite, SWT.NONE);
		tableHolder.setLocation(0, 0);
		tableHolder.setSize(540, 479);

		TabItem expense_tabItem = new TabItem(tableHolder, SWT.NONE);
		expense_tabItem.setText("My Expenses");
		expense_table = new Table(tableHolder, SWT.FULL_SELECTION);
		expense_table.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDoubleClick(MouseEvent e) {
				EditRemoveExpense ere = new EditRemoveExpense(home_composite
						.getShell(), 65);
				TableItem[] itemList = expense_table.getSelection();
				try {
					ere.open((Expense) itemList[0].getData(), mc);
					refreshExpenseTable("");
					refreshIncomeTable("");
					refreshGoalTable("");
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		expense_tabItem.setControl(expense_table);
		expense_table.setHeaderVisible(true);
		expense_table.setLinesVisible(true);
		for (int i = 0; i < cashflow_titles.length; i++) {
			TableColumn column = new TableColumn(expense_table, SWT.NONE);
			column.setResizable(false);
			column.setText(cashflow_titles[i]);
		}

		TabItem income_tabItem = new TabItem(tableHolder, SWT.NONE);
		income_tabItem.setText("My Income");
		income_table = new Table(tableHolder, SWT.FULL_SELECTION);
		income_table.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDoubleClick(MouseEvent e) {
				EditRemoveIncome eri = new EditRemoveIncome(home_composite
						.getShell(), 65);
				TableItem[] itemList = income_table.getSelection();
				try {
					eri.open((Income) itemList[0].getData(), mc);
					refreshExpenseTable("");
					refreshIncomeTable("");
					refreshGoalTable("");
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		income_tabItem.setControl(income_table);
		income_table.setHeaderVisible(true);
		income_table.setLinesVisible(true);
		for (int i = 0; i < cashflow_titles.length; i++) {
			TableColumn column = new TableColumn(income_table, SWT.NONE);
			column.setResizable(false);
			column.setText(cashflow_titles[i]);
		}

		TabItem goal_tabItem = new TabItem(tableHolder, SWT.NONE);
		goal_tabItem.setText("My Goals");
		goal_table = new Table(tableHolder, SWT.FULL_SELECTION);
		goal_table.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDoubleClick(MouseEvent e) {
				EditRemoveGoal erg = new EditRemoveGoal(home_composite
						.getShell(), 65);
				TableItem[] itemList = goal_table.getSelection();
				try {
					erg.open((Goal) itemList[0].getData(), mc);
					refreshExpenseTable("");
					refreshIncomeTable("");
					refreshGoalTable("");
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		goal_tabItem.setControl(goal_table);
		goal_table.setHeaderVisible(true);
		goal_table.setLinesVisible(true);
		for (int i = 0; i < goal_titles.length; i++) {
			TableColumn column = new TableColumn(goal_table, SWT.NONE);
			column.setResizable(false);
			column.setText(goal_titles[i]);
		}
		// Refresh all the tables
		refreshExpenseTable(search);
		refreshIncomeTable(search);
		refreshGoalTable(search);
	}

	// @author U096819H
	public void refreshCatPie(Composite incomePie, Composite expensePie,
			Display display) {
		PieChartCategory pcc = new PieChartCategory();
		try {
			pcc.generateChart(mc);
			Image catExpPie = new Image(display, graphDir + "/catExp.png");
			Image catIncPie = new Image(display, graphDir + "/catInc.png");
			expensePie.setBackgroundImage(catExpPie);
			incomePie.setBackgroundImage(catIncPie);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// @author U096819H
	public void refreshSrcPie(Composite incomePie, Composite expensePie,
			Display display) {
		PieChartSource pcc = new PieChartSource();
		try {
			pcc.generateChart(mc);
			Image catExpPie = new Image(display, graphDir + "/srcExp.png");
			Image catIncPie = new Image(display, graphDir + "/srcInc.png");
			expensePie.setBackgroundImage(catExpPie);
			incomePie.setBackgroundImage(catIncPie);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// @author U096819H
	// Refresh goal table
	public void refreshGoalTable(String _search)
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {
		ArrayList<Goal> list;
		if (_search.equals("")) {
			list = mc.GetAllGoal();
		} else {
			list = null;
		}
		Goal goal;
		goal_table.removeAll();

		/*
		 * Table Headers :: "Title", "Amount", "Amount Achieved", "Active",
		 * "Start Date", "End Date", "Date"
		 */

		for (int i = 0; i < list.size(); i++) {
			goal = list.get(i);
			TableItem item = new TableItem(goal_table, SWT.NONE);
			item.setData(goal);
			item.setText(0, goal.getName());
			item.setText(1, String.valueOf(goal.getTotalAmount()));
			item.setText(2, String.valueOf(goal.getAmountAchieved()));
			item.setText(3, String.valueOf(goal.isActive()));
			SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy");
			item.setText(4, sdf.format(goal.getStartDate().getTime()));
			item.setText(5, sdf.format(goal.getEndDate().getTime()));
		}
		for (int i = 0; i < goal_titles.length; i++) {
			goal_table.getColumn(i).pack();
		}
	}

	// @author U096819H
	// Refresh expense table
	public void refreshExpenseTable(String _search)
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException, NullVariableFound {
		ArrayList<Expense> list;
		if (_search.equals("")) {
			list = mc.GetAllExpense();
		} else {
			list = mc.GetExpenseByKeyword(_search);
		}

		Expense expense;
		expense_table.clearAll();
		expense_table.removeAll();
		System.out.println(":::: " + list.size() + " ::: ");

		for (int i = 0; i < list.size(); i++) {
			expense = list.get(i);
			TableItem item = new TableItem(expense_table, SWT.NONE);
			item.setData(expense);
			item.setText(0, expense.getName());
			item.setText(1, expense.getCategory().getName());
			item.setText(2, String.valueOf(expense.getAmount()));
			item.setText(3, expense.getSource().getName());
			SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy");
			item.setText(4, sdf.format(expense.getDate().getTime()));
			if (expense.getRecurs()) {
				item.setText(5, expense.getRecursPeriod().toString());
			} else {
				item.setText(5, "");
			}
		}

		for (int i = 0; i < cashflow_titles.length; i++) {
			expense_table.getColumn(i).pack();
		}
	}

	// @author U096819H
	// Refresh income table
	public void refreshIncomeTable(String _search)
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException, NullVariableFound {
		ArrayList<Income> list;
		if (_search.equals("")) {
			list = mc.GetAllIncome();
		} else {
			try {
				list = mc.GetIncomeByKeyword(_search);
			} catch (NullVariableFound e) {
				// TODO Auto-generated catch block
				list = mc.GetIncomeByKeyword(_search);
			}
		}
		Income income;
		income_table.removeAll();

		for (int i = 0; i < list.size(); i++) {
			income = list.get(i);
			TableItem item = new TableItem(income_table, SWT.NONE);
			item.setData(income);
			item.setText(0, income.getName());
			item.setText(1, income.getCategory().getName());
			item.setText(2, String.valueOf(income.getAmount()));
			item.setText(3, income.getSource().getName());
			SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy");
			item.setText(4, sdf.format(income.getDate().getTime()));
			if (income.getRecurs()) {
				item.setText(5, income.getRecursPeriod().toString());
			} else {
				item.setText(5, "");
			}
		}

		for (int i = 0; i < cashflow_titles.length; i++) {
			income_table.getColumn(i).pack();
		}
	}

	//@author U096819H
	protected void createContents() {
		setText("EzXpns: Team40");
		setSize(800, 600);
	}

	@Override
	protected void checkSubclass() {
	}
}
